﻿using System;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace ICodeShare.UI.Converters
{
    [ValueConversion(typeof(Thickness), typeof(Thickness))]
    public sealed class ThicknessToMultipleThicknessConverter : IValueConverter
    {
        #region Members
        /// <summary>
        /// 倍数
        /// </summary>
        private double _multiple = 1.0;

        /// <summary>
        /// 左倍数
        /// </summary>
        private double _multipleLeft = 1.0;
        /// <summary>
        /// 上倍数
        /// </summary>
        private double _multipleTop = 1.0;
        /// <summary>
        /// 右倍数
        /// </summary>
        private double _multipleRight = 1.0;
        /// <summary>
        /// 下倍数
        /// </summary>
        private double _multipleBottom = 1.0;
        #endregion

        #region Constructors
        /// <summary>
        /// 
        /// </summary>
        public ThicknessToMultipleThicknessConverter()
        {

        }

        /// <summary>
        ///  实例化一个<see cref="ThicknessToMultipleThicknessConverter"/>实例
        /// </summary>
        /// <param name="multiple">倍数，用于一次设置全部</param>
        /// <param name="multipleLeft"></param>
        /// <param name="multipleTop"></param>
        /// <param name="multipleRight"></param>
        /// <param name="multipleBottom"></param>
        public ThicknessToMultipleThicknessConverter(double multiple, double multipleLeft, double multipleTop, double multipleRight, double multipleBottom)
        {
            this.Multiple = multiple;
            this.MultipleLeft = multipleLeft;
            this.MultipleTop = multipleTop;
            this.MultipleRight = multipleRight;
            this.MultipleBottom = multipleBottom;
        }
        #endregion

        #region Properties
        /// <summary>
        /// 倍数
        /// </summary>
        public double Multiple
        {
            get { return this._multiple; }
            set 
            {
                this._multiple = value;
                    _multipleLeft = value;
                    _multipleTop = value;
                    _multipleRight = value;
                    _multipleBottom = value;
             }
        }

        /// <summary>
        /// 左倍数
        /// </summary>
        public double MultipleLeft
        {
            get { return this._multipleLeft; }
            set { this._multipleLeft = value; }
        }

        /// <summary>
        /// 上倍数
        /// </summary>
        public double MultipleTop
        {
            get { return this._multipleTop; }
            set { this._multipleTop = value; }
        }

        /// <summary>
        /// 右倍数
        /// </summary>
        public double MultipleRight
        {
            get { return this._multipleRight; }
            set { this._multipleRight = value; }
        }

        /// <summary>
        /// 下倍数
        /// </summary>
        public double MultipleBottom
        {
            get { return this._multipleBottom; }
            set { this._multipleBottom = value; }
        }

        #endregion

        #region Base Class Overrides 基类方法重写

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is Thickness))
            {
                return DependencyProperty.UnsetValue;
            }

            var source = (Thickness)value;

            var parameters = parameter as string;

            if (parameters != null)
            {
                var propertyNames = parameters.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                if (propertyNames.Length > 0)
                {
                    var thickness = new Thickness(0);

                    var changed = false;

                    foreach (var propertyName in propertyNames)
                    {
                        switch (propertyName.Trim().ToLower())
                        {
                            case "left":
                                thickness.Left = source.Left * _multipleLeft;
                                changed = true;
                                break;
                            case "top":
                                thickness.Top = source.Top * _multipleTop;
                                changed = true;
                                break;
                            case "right":
                                thickness.Right = source.Right * _multipleRight;
                                changed = true;
                                break;
                            case "bottom":
                                thickness.Bottom = source.Bottom * _multipleBottom;
                                changed = true;
                                break;
                        }
                    }

                    if (changed)
                    {
                        return thickness;
                    }
                }
            }

            return new Thickness(source.Left * _multipleLeft, source.Top * _multipleTop, source.Right * _multipleRight, source.Bottom * _multipleBottom);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is double))
            {
                return DependencyProperty.UnsetValue;
            }
            var source = (Thickness)value;
            var parameters = parameter as string;
            if (parameter != null)
            {
                var propertyNames = parameters.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                if (propertyNames.Length > 0)
                {
                    var thickness = new Thickness(0);

                    var changed = false;


                    foreach (var propertyName in propertyNames)
                    {
                        switch (propertyName.Trim().ToLower())
                        {
                            case "left":
                                if (_multipleLeft != 0)
                                {
                                    thickness.Left = Math.Round(source.Left / _multipleLeft, 2);
                                    changed = true;
                                }
                                break;
                            case "top":
                                if (_multipleTop != 0)
                                {
                                    thickness.Top = Math.Round(source.Top / _multipleTop, 2);
                                    changed = true;
                                }
                                break;
                            case "right":
                                if (_multipleRight != 0)
                                {
                                    thickness.Right = Math.Round(source.Right / _multipleRight, 2);
                                    changed = true;
                                }
                                break;
                            case "bottom":
                                if (_multipleBottom != 0)
                                {
                                    thickness.Bottom = Math.Round(source.Bottom / _multipleBottom, 2);
                                    changed = true;
                                }
                                break;
                        }
                    }

                    if (changed)
                    {
                        return thickness;
                    }
                }
            }

            return new Thickness(((_multipleLeft != 0) ? Math.Round(source.Left / _multipleLeft, 2) : 0), ((_multipleTop != 0) ? Math.Round(source.Top / _multipleTop, 2) : 0),
                ((_multipleRight != 0) ? Math.Round(source.Right / _multipleRight, 2) : 0), ((_multipleBottom != 0) ? Math.Round(source.Bottom / _multipleBottom, 2) : 0));
        }

        #endregion
    }
}
